package com.nine.algorithm.array;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * @author nine
 * @version 1.0
 * @description 动态数组
 * @date 24/4/25 21:54
 */
public class DynamicArray implements Iterable<Integer> {

	// 逻辑大小
	private int size = 0;
	// 容量
	private int capacity = 8;

	// 数组，可以在第一次添加元素时，赋值
	// private int[] array = new int[capacity];
	private int[] array = {};

	// 获取数组大小
	public int getSize() {
		return size;
	}

	public int get(int index) {
		return array[index];
	}

	/**
	 * 添加元素【向最后位置 size 添加元素】
	 *
	 * @param element 待添加的元素
	 */
	public void addLast(int element) {
		// array[size] = element;
		// size++;
		add(size, element);
	}

	/**
	 * 精简优化版本【向 [0 .. size] 位置添加元素 】
	 * Java中的位运算符：
	 * >>表示右移，如果该数为正，则高位补0，若为负数，则高位补1；
	 * >>>表示无符号右移，也叫逻辑右移，不管正负数，最高位一律补0
	 *
	 * @param index   索引位置
	 * @param element 待添加元素
	 */
	public void add(int index, int element) {
		// 容量检查
		checkAndGrow();

		// 添加逻辑
		if (index >= 0 && index < size) {
			// 数组拷贝
			// 原数组 {1，2，4，5}，需要在 index = 2 处，添加 element = 3
			// 要进行数组拷贝，将原数组中 index 后面的元素，依次向后移动一位
			System.arraycopy(array, index, array, index + 1, size - index);
		}
		array[index] = element;
		size++;
	}

	private void checkAndGrow() {
		// 容量检查
		if (size == 0) {
			array = new int[capacity];
		}
		else if (size == capacity) {
			// 进行扩容，一般是 1.5倍
			capacity += capacity >> 1;
			int[] newArray = new int[capacity];
			System.arraycopy(array, 0, newArray, 0, size);
			array = newArray;
		}
	}

	public int remove(int index) {
		int removed = array[index];
		if (index < size - 1) {
			// 数组拷贝
			System.arraycopy(array, index + 1, array, index, size - index - 1);
		}
		size--;
		return removed;
	}


	/**
	 * @param index
	 * @param element
	 */
	public void add_01(int index, int element) {
		if (index >= 0 && index < size) {
			// 数组拷贝
			// 原数组 {1，2，4，5}，需要在 index = 2 处，添加 element = 3
			// 要进行数组拷贝，将原数组中 index 后面的元素，依次向后移动一位
			System.arraycopy(array, index, array, index + 1, size - index);
			array[index] = element;
			size++;
		}
		else if (index == size) {
			array[index] = element;
			size++;
		}
	}

	/********** 遍历 **************/

	/**
	 * 遍历打印【只能用来打印】
	 * 可以使用函数式接口，用来处理一些其他事务
	 * 1. 提供 array[i]
	 * 2. 返回 void
	 * 可以使用 Consumer 接口
	 */
	public void forEach1() {
		for (int i = 0; i < size; i++) {
			if (i == size - 1) {
				System.out.print(array[i]);
			}
			else {
				System.out.print(array[i] + ",");
			}
		}
	}

	/**
	 * 遍历方法一：函数式接口处理
	 *
	 * @param consumer
	 */
	public void forEach2(Consumer<Integer> consumer) {
		for (int i = 0; i < size; i++) {
			// 提供 array[i]
			// 返回 void
			consumer.accept(array[i]);
		}
	}

	/**
	 * 遍历方法二
	 *
	 * @return
	 */
	@Override
	public Iterator<Integer> iterator() {
		return new Iterator<Integer>() {
			int i = 0;

			// 有没有下一个元素
			@Override
			public boolean hasNext() {
				return i < size;
			}

			// 返回当前元素，并移动到下一个元素
			@Override
			public Integer next() {
				return array[i++];
			}
		};
	}

	/**
	 * 遍历方法三：流
	 */
	public IntStream stream() {
		return IntStream.of(Arrays.copyOfRange(array, 0, size));
	}
}
